import sys
from typing_extensions import TypeAlias

# Because UUID has properties called int and bytes we need to rename these temporarily.
_Int: TypeAlias = int
_Bytes: TypeAlias = bytes
_FieldsType: TypeAlias = tuple[int, int, int, int, int, int]

if sys.version_info >= (3, 7):
    from enum import Enum

    class SafeUUID(Enum):
        safe: int
        unsafe: int
        unknown: None

class UUID:
    if sys.version_info >= (3, 7):
        def __init__(
            self,
            hex: str | None = ...,
            bytes: _Bytes | None = ...,
            bytes_le: _Bytes | None = ...,
            fields: _FieldsType | None = ...,
            int: _Int | None = ...,
            version: _Int | None = ...,
            *,
            is_safe: SafeUUID = ...,
        ) -> None: ...
        @property
        def is_safe(self) -> SafeUUID: ...
    else:
        def __init__(
            self,
            hex: str | None = ...,
            bytes: _Bytes | None = ...,
            bytes_le: _Bytes | None = ...,
            fields: _FieldsType | None = ...,
            int: _Int | None = ...,
            version: _Int | None = ...,
        ) -> None: ...

    @property
    def bytes(self) -> _Bytes: ...
    @property
    def bytes_le(self) -> _Bytes: ...
    @property
    def clock_seq(self) -> _Int: ...
    @property
    def clock_seq_hi_variant(self) -> _Int: ...
    @property
    def clock_seq_low(self) -> _Int: ...
    @property
    def fields(self) -> _FieldsType: ...
    @property
    def hex(self) -> str: ...
    @property
    def int(self) -> _Int: ...
    @property
    def node(self) -> _Int: ...
    @property
    def time(self) -> _Int: ...
    @property
    def time_hi_version(self) -> _Int: ...
    @property
    def time_low(self) -> _Int: ...
    @property
    def time_mid(self) -> _Int: ...
    @property
    def urn(self) -> str: ...
    @property
    def variant(self) -> str: ...
    @property
    def version(self) -> _Int | None: ...
    def __int__(self) -> _Int: ...
    def __eq__(self, other: object) -> bool: ...
    def __lt__(self, other: UUID) -> bool: ...
    def __le__(self, other: UUID) -> bool: ...
    def __gt__(self, other: UUID) -> bool: ...
    def __ge__(self, other: UUID) -> bool: ...

def getnode() -> int: ...
def uuid1(node: _Int | None = ..., clock_seq: _Int | None = ...) -> UUID: ...
def uuid3(namespace: UUID, name: str) -> UUID: ...
def uuid4() -> UUID: ...
def uuid5(namespace: UUID, name: str) -> UUID: ...

NAMESPACE_DNS: UUID
NAMESPACE_URL: UUID
NAMESPACE_OID: UUID
NAMESPACE_X500: UUID
RESERVED_NCS: str
RFC_4122: str
RESERVED_MICROSOFT: str
RESERVED_FUTURE: str
